using System.Collections.Generic;
using Microsoft.DirectX.Direct3D;
using Light = RPGOnline.Controls.Map.Layers.Lighting.Light;
using LightsCollection = RPGOnline.Controls.Map.Layers.Lighting.LightsCollection;

namespace RPGOnline.Controls.Map.Layers.Obstruction
{
    public class ObstructionLayer
    {
        private readonly Map m_map;
        private readonly LightsCollection m_lightsCollection;
        private ObstructionTile[,] m_obstructions;

        public ObstructionLayer(Map map, LightsCollection lightsCollection)
        {
            m_map = map;
            m_lightsCollection = lightsCollection;
            m_obstructions = new ObstructionTile[m_map.MapSize.Width,m_map.MapSize.Height];
        }

        public void Draw(Device device)
        {
            device.VertexFormat = CustomVertex.TransformedColored.Format;
            device.RenderState.AlphaBlendEnable = true;

            for (int y = 0; y < m_map.MapSize.Height; y++)
            {
                for (int x = 0; x < m_map.MapSize.Width; x++)
                {
                    if (m_obstructions[x, y] == null)
                        continue;

                    foreach (Light light in m_lightsCollection)
                    {
                        if(m_obstructions[x, y].WillCastShadows(light))
                        {
                            List<ShadowPolygon> shadowPolygons = m_obstructions[x, y].CastShadows(light);
                            foreach (ShadowPolygon shadowPolygon in shadowPolygons)
                            {
                                device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, shadowPolygon.TriangleStrip());
                            }
                        }
                    }
                }
            }
        }

        public void SetObstruction(int x, int y)
        {
            m_obstructions[x,y] = new ObstructionTile(m_map);
            TrimObstructions();
        }

        private void TrimObstructions()
        {
            for(int y = 0; y < m_map.MapSize.Height; y++)
            {
                for(int x = 0; x < m_map.MapSize.Width; x++)
                {
                    if (m_obstructions[x, y] == null)
                        continue;

                    //TODO: Change Layer[0] with something more sophisticated that supports multi layer shadows
                    m_obstructions[x,y].UpdateObstructions(m_obstructions, m_map.Layers[0][x,y], x, y);
                }
            }
        }

        public void RemoveObstruction(int x, int y)
        {
            m_obstructions[x, y] = null;
            TrimObstructions();
        }
    }
}